import random

from django.core.cache import caches, cache
from django.db import transaction
from rest_framework import viewsets
from rest_framework.response import Response


class CacheModelSetError(Exception):
    ...


class CacheModelSet(viewsets.ModelViewSet):
    cache_key_template = None
    expires_during = [10, 100]

    def get_cache_key_template(self) -> str:
        if self.cache_key_template is not None:
            return self.cache_key_template
        raise CacheModelSetError("需要提供缓存模版")

    def get_pk(self):
        lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
        return self.kwargs[lookup_url_kwarg]

    def remove_cache(self, _id):
        cache_key_template = self.get_cache_key_template()
        path = cache_key_template.replace("{handler}", _id)
        _all = cache_key_template.replace("{handler}", "all")
        cache.delete(path)
        cache.delete(_all)

    def list(self, request, *args, **kwargs):
        cache_key_template = self.get_cache_key_template()
        cache_key_template.replace("{handler}", "all")

        ret = cache.get(cache_key_template)
        if ret is None:
            print("【all】缓存失效设置缓存")
            ret = super().list(request, *args, **kwargs).data
            cache.set(cache_key_template, ret, self.get_expires_time())
        else:
            print("【all】缓存命中")
        return Response(ret)

    def get_expires_time(self):
        expires_during: list = self.expires_during
        return random.randint(*expires_during)

    def retrieve(self, request, *args, **kwargs):
        cache_key_template = self.get_cache_key_template()
        _id = self.get_pk()
        cache_key_template.replace("{handler}", _id)
        ret = cache.get(cache_key_template)
        if ret is None:
            print("缓存失效设置缓存")
            ret = super().retrieve(request, *args, **kwargs).data
            cache.set(cache_key_template, ret, self.get_expires_time())
        else:
            print("缓存命中")
        return Response(ret)

    def destroy(self, request, *args, **kwargs):
        print("缓存更新")
        value = super().destroy(request, *args, **kwargs)
        self.remove_cache(self.get_pk())
        return value

    def update(self, request, *args, **kwargs):
        print("缓存更新")
        value = super().update(request, *args, **kwargs)
        self.remove_cache(self.get_pk())
        return value

    def create(self, request, *args, **kwargs):
        value = super().create(request, *args, **kwargs)
        self.remove_cache("all")
        return value
